export class Vec3 {
    /**
     * @param {number | Entity} x 坐标数字或一个存在 getX() getY() getZ() 方法的对象
     * @param {number} y 坐标数字 若x不为数字则不用填
     * @param {number} z 坐标数字 若x不为数字则不用填
     */
    constructor(x,y=x,z=x) {
        if(typeof x === "number" || (typeof x === "string" && !isNaN(x))) {
            this.x = x;
            this.y = y;
            this.z = z;
        } else {
            this.x = x.getX();
            this.y = x.getY();
            this.z = x.getZ();
        }
    }

    getX() { return this.x }
    getY() { return this.y }
    getZ() { return this.z }

    /**
     * 将两个坐标相加
     * @param {Vec3 | Vec3i} other 
     * @returns 
     */
    add(other) {
        return new Vec3(this.x + other.x, this.y + other.y, this.z + other.z);
    }

    toString() {
        return "x: " + this.x + ", y: " + this.y + ", z: " + this.z + " ";
    }
    
    subtract(other) {
        return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
    }
        
    lengthSquared() {
        return this.x * this.x + this.y * this.y + this.z * this.z;
    }

    /**
     * 计算两个点的距离
     * @param {Vec3 | Vec3i} other 另一个点
     * @returns {number} 两个点的距离
     */
    distance(other) {
        return Math.sqrt((this.x - other.x)**2 + (this.y  - other.y)**2 + (this.z - other.z)**2);
    }

    /**
     * 坐标是否在指定区域内
     * @param {Vec3 | Vec3i} p1 区域的一个点
     * @param {Vec3 | Vec3i} p2 斜对角的另一个点
     * @returns {boolean}
     */
    isIn(p1,p2) {
        const ps = new Vec3( (p1.x < p2.x ? p1.x : p2.x) , (p1.y < p2.y ? p1.y : p2.y) , (p1.z < p2.z ? p1.z : p2.z) );
        const px = new Vec3( (p1.x > p2.x ? p1.x : p2.x) , (p1.y > p2.y ? p1.y : p2.y) , (p1.z > p2.z ? p1.z : p2.z) );
        return (ps.x < this.x && this.x < px.x && ps.y < this.y && this.y < px.y && ps.z < this.z && this.z < px.z)
    }

    /**
     * @returns {Vec3i}
     */
    toVec3i() {
        return new Vec3i(this.x, this.y, this.z);
    }
}